From ea830aee5d21c6a5992381c0aea7fce608b9518f Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Wed, 20 Aug 2014 20:12:35 +0200 Subject: [PATCH] button: Track gesture point to maintain priv->in_button This makes the active state work invariably with both mouse/touch, and regardless of X11 pointer emulation being friendly and sending crossing events for the emulated pointer events in the latter. This makes GtkButtons' active state look correct when pressing on touchscreens on wayland. https://bugzilla.gnome.org/show_bug.cgi?id=731380 --- gtk/gtkbutton.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c index c1f4d0d0f4..9c1dcb441c 100644 --- a/gtk/gtkbutton.c +++ b/gtk/gtkbutton.c @@ -592,6 +592,7 @@ multipress_pressed_cb (GtkGestureMultiPress *gesture, if (priv->focus_on_click && !gtk_widget_has_focus (widget)) gtk_widget_grab_focus (widget); + priv->in_button = TRUE; g_signal_emit (button, button_signals[PRESSED], 0); gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED); } @@ -604,10 +605,44 @@ multipress_released_cb (GtkGestureMultiPress *gesture, GtkWidget *widget) { GtkButton *button = GTK_BUTTON (widget); + GtkButtonPrivate *priv = button->priv; + GdkEventSequence *sequence; + GdkDevice *source; + + sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture)); + source = gdk_event_get_source_device (gtk_gesture_get_last_event (GTK_GESTURE (gesture), + sequence)); + if (gdk_device_get_source (source) == GDK_SOURCE_TOUCHSCREEN) + priv->in_button = FALSE; g_signal_emit (button, button_signals[RELEASED], 0); } +static void +multipress_gesture_update_cb (GtkGesture *gesture, + GdkEventSequence *sequence, + GtkButton *button) +{ + GtkButtonPrivate *priv = button->priv; + GtkAllocation allocation; + gboolean in_button; + gdouble x, y; + + if (sequence != gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture))) + return; + + gtk_widget_get_allocation (GTK_WIDGET (button), &allocation); + gtk_gesture_get_point (gesture, sequence, &x, &y); + + in_button = (x >= 0 && y >= 0 && x < allocation.width && y < allocation.height); + + if (priv->in_button != in_button) + { + priv->in_button = in_button; + gtk_button_update_state (button); + } +} + static void gtk_button_init (GtkButton *button) { @@ -646,6 +681,7 @@ gtk_button_init (GtkButton *button) gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->gesture), GDK_BUTTON_PRIMARY); g_signal_connect (priv->gesture, "pressed", G_CALLBACK (multipress_pressed_cb), button); g_signal_connect (priv->gesture, "released", G_CALLBACK (multipress_released_cb), button); + g_signal_connect (priv->gesture, "update", G_CALLBACK (multipress_gesture_update_cb), button); gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->gesture), GTK_PHASE_BUBBLE); } -- 2.30.2